#ifndef GAMELOGIC_H
#define GAMELOGIC_H

#include "ICliWindow.h"
#include "cfgmgr.h"
#include "downloadmanager.h"
#include "qos.h"
#include "uploader.h"

#include <QString>
#include <map>
#include <QSystemTrayIcon>
#include <QProcess>
#include <QNetworkAccessManager>

#include "Macros.h"
#if defined(GM_PLAT_ZTJ_TOP1GAME)
#include "ztj_top1game.h"
#else
#include "defaultlang.h"
#endif

// 定义启动参数key
#define PARAM_SIMPLEMODE "simplemode"
#define PARAM_HIDE "hide"
#define PARAM_PLATFORM "platform"
#define PARAM_CMD "cmd"

enum GameMode
{
    /**正常模式，显示选服页*/
    Normal,
    /**简易模式，不需要选服步骤*/
    Simple,
    /**静默模式，通常是安装器首次安装完成后拉起游戏*/
    Hide
};

struct AppVars
{
    GameMode mode;
    QString platform;
    QString pfIni;
    QString shellCfg;
    QString localPkg;
    QString enterQuery;
    QString uid;
    int minVer = 0;

#ifdef GM_PLAT_ZTJ_TOP1GAME
    QString token;
#endif
};

enum DownloadTask
{
    DT_None,
    DT_PlatCfg,
    DT_ShellCfg,
    DT_Pkg,
    DT_Shell
};

struct DownloadItem
{
    DownloadTask task;
    QString desc;
    Qos::QosType errQosType;
    QString errQosDesc;
};

enum TimerTask
{
    CheckUnityLog = 1,
    CheckUnityCmd = 2
};

class GameLogic: public QObject
{
    Q_OBJECT
public:
    GameLogic();
    ~GameLogic();

    void setUp(QApplication *app, QList<QString> argList, std::unique_ptr<std::map<QString, QString>> argMap);

    CfgMgr cfgMgr;

private:
    enum GameState
    {
        None,
        DownloadPlatCfg,
        QueryMin,
        DownloadPkg,
        UnzipPkg,
        WaitEnterGame
    };

    QList<QString> m_argList;
    std::unique_ptr<std::map<QString, QString>> m_argMap;
    QApplication *m_app;
    ICliWindow *m_window;
    std::unique_ptr<QProcess> m_unityProc;

    QSystemTrayIcon m_sysTray;
    DownloadManager m_dlMgr;
    QNetworkAccessManager m_netMgr;
    Qos m_qos;
    Uploader m_uploader;

    struct AppVars m_vars;
    GameState m_state;
    int m_callUnityAt = 0;
    QString m_unityCmdKey;
    int m_lastCmdSeq = 0;
    bool m_isUnityOK = false;
    bool m_canExit = false;
    bool m_hasCheckUpdate = false;

    std::unique_ptr<QTimer> m_timer;
    int m_timerTaskFlag = 0;

    std::map<QUrl, DownloadItem> m_downloadTaskMap;

    void unzipGameZip();
    void launchUnity();

    bool isUnityRunning();
    QString findUnityLog();

    void appendDownload(DownloadTask task, const QUrl &url, const QString &desc,
                        Qos::QosType errQosType, const QString &errQosDesc);

    void startTimer(int taskFlag);
    void checkUnityStatus();
    void checkUnityCmd();
    void uploadLog();

    void resetWindow();
    void safeExit();

    void checkUpdate();
    void continueUpdate();

public slots:
    void onDownloadStart(const QUrl &url);
    void onDownloadProgress(const QUrl &url, qint64 bytesReceived, qint64 bytesTotal);
    void onDownloadMilestone(const QUrl &url);
    void onDownloadFinished();
    void onDownloadError(const QUrl &url);

private slots:
    void onExitMenu();
    void onSystemTrayIconActivated(QSystemTrayIcon::ActivationReason reason);
    void checkPkg();
    void onPkgReady();
    bool checkD3d9();
    void onEnterGame(const QString &query);
    void onUnityStarted();
    void onTimer();

#ifdef GM_PLAT_ZTJ_TOP1GAME
    void onZtjTop1GameLogin(QNetworkReply *reply);
#endif
};

#endif // GAMELOGIC_H
